# coding:utf-8

import wx.lib.rcsizer as rcs
import Config

try:
    from agw import fourwaysplitter as FWS
except ImportError:  # if it's not there locally, try the wxPython lib.
    try:
        import wx.lib.agw.fourwaysplitter as FWS
    except ImportError:
        exit()

# 菜单ID
from AppIds import *

import wx.lib.newevent

# Frame start
SERIAL_GENIUS_FS_CHAR = 0x0F
# Slash
SERIAL_GENIUS_SL_CHAR = 0x1F


# 变量助手列表
class PanelModuleVariableList(wx.ListCtrl):
    def __init__(self, parent):
        wx.ListCtrl.__init__(
            self, parent, -1,
            style=wx.LC_REPORT | wx.LC_VIRTUAL | wx.LC_HRULES | wx.LC_VRULES
        )

        self.parent = parent

        self.InsertColumn(0, u"编号")
        self.InsertColumn(1, "INT8U")
        self.InsertColumn(2, "INT8S")
        self.InsertColumn(3, "INT16U")
        self.InsertColumn(4, "INT16S")
        self.InsertColumn(5, "INT32U")
        self.InsertColumn(6, "INT32S")

        self.SetColumnWidth(0, 50)
        self.SetColumnWidth(1, 50)
        self.SetColumnWidth(2, 50)
        self.SetColumnWidth(3, 80)
        self.SetColumnWidth(4, 80)
        self.SetColumnWidth(5, 100)
        self.SetColumnWidth(6, 100)

        self.SetItemCount(256)

        self.refreshTimer = wx.Timer(self)
        self.Bind(wx.EVT_TIMER, self.RefreshData)
        self.refreshTimer.Start(1000)
        self.dataChanged = False

    # 刷新数据
    def RefreshData(self, event):
        if self.dataChanged:
            self.Refresh()
        self.dataChanged = False

    # ---------------------------------------------------
    # These methods are callbacks for implementing the
    # "virtualness" of the list...  Normally you would
    # determine the text, attributes and/or image based
    # on values from some external data source, but for
    # this demo we'll just calculate them
    def OnGetItemText(self, item, col):
        value = self.parent.Data[item][col - 1]
        if self.parent.hexMode:
            if col == 0:
                return ('0x%02X' % item)
            else:
                if col <= 2:
                    if value >= 0:
                        return ('0x%02X' % value)
                    else:
                        return ('0x%02X' % (value + 0x100))
                elif col <= 4:
                    if value >= 0:
                        return ('0x%04X' % value)
                    else:
                        return ('0x%04X' % (value + 0x10000))
                else:
                    if value >= 0:
                        return ('0x%08X' % value)
                    else:
                        return ('0x%08X' % (value + 0x100000000))
        else:
            if col == 0:
                return item
            else:
                return value

    def OnGetItemImage(self, item):
        return -1

    def OnGetItemAttr(self, item):
        return None


# 变量助手      
class Variable(wx.Panel):
    def __init__(self, parent):
        wx.Panel.__init__(self, parent, style=wx.BORDER_DOUBLE)

        ############# 状态信息 ############
        # 该模块是否启用
        self.isUsing = False

        ############# 配置信息 ############
        # self.Data= [[0] * 6] * 256
        self.Data = [[0 for col in range(7)] for row in range(256)]
        self.hexMode = False
        self.dataBuffer = []
        # 命令解析状态
        # 0 无
        # 1 INT8U
        # 2 INT8S
        # 3 INT16U
        # 4 INT16S
        # 5 INT32U
        # 6 INT32S
        self.dataParseCurStatus = 0
        self.dataparseCurLength = 0

        ############# 开始布局 ###########
        gridSizer = rcs.RowColSizer()

        rowTotal = 3
        colTotal = 2

        # 标题
        title = wx.StaticText(self, -1, u"变量助手")
        title.SetFont(wx.Font(8, wx.FONTFAMILY_DEFAULT, wx.FONTSTYLE_NORMAL, wx.FONTWEIGHT_BOLD))
        gridSizer.Add(title, pos=(0, 0), size=(1, colTotal), flag=wx.EXPAND | wx.ALIGN_CENTER_VERTICAL)

        # 变量显示区域
        self.listData = PanelModuleVariableList(self)
        gridSizer.Add(self.listData, pos=(1, 0), size=(1, colTotal), flag=wx.EXPAND)

        # 清空
        btn = wx.Button(self, -1, u"清空")
        self.Bind(wx.EVT_BUTTON, self.OnClearData, btn)
        gridSizer.Add(btn, pos=(2, 0), size=(1, 1), flag=wx.ALIGN_CENTER_VERTICAL)

        # 显示模式
        ck = wx.CheckBox(self, -1, u"十六进制显示")
        ck.Bind(wx.EVT_CHECKBOX, self.OnHexMode)
        gridSizer.Add(ck, pos=(2, 1), size=(1, 1), flag=wx.EXPAND | wx.ALIGN_CENTER_VERTICAL)
        if Config.APP_CONFIG['module_variable']['hexMode'] == '1':
            ck.SetValue(True)
            self.hexMode = True

        # 调试时候显示字符
        # self.debugText=wx.StaticText(self, -1, "")
        # gridSizer.Add(self.debugText, pos=(2,1), size=(1, colTotal), flag=wx.EXPAND|wx.ALIGN_CENTER_VERTICAL)

        # 设置变宽信息
        gridSizer.AddGrowableCol(1)
        gridSizer.AddGrowableRow(1)

        ############# 结束布局 ###########
        self.SetSizer(gridSizer)
        self.SetAutoLayout(True)

    # 获取数据部分中下一个数据（如果转义自动去除转义符号）
    def GetNextDataByte(self):
        if self.dataBuffer[0] == SERIAL_GENIUS_SL_CHAR:
            self.dataBuffer.pop(0)
        return self.dataBuffer.pop(0)

     # 新增串口数据，被串口接收所调用
    def RecvData(self, data):
        self.dataBuffer.extend(data)
        # 解析数据
        while (self.dataParseCurStatus == 0 and len(self.dataBuffer) >= 5) or (
                self.dataParseCurStatus != 0 and len(self.dataBuffer) >= self.dataparseCurLength):
            try:
                if self.dataParseCurStatus == 0:
                    # 找到帧头
                    while len(self.dataBuffer) > 1:
                        if self.dataBuffer[0] == SERIAL_GENIUS_FS_CHAR:
                            break
                        if self.dataBuffer[0] == SERIAL_GENIUS_SL_CHAR:
                            self.dataBuffer.pop(0)
                        self.dataBuffer.pop(0)

                    if len(self.dataBuffer) < 5:
                        break

                    # 0F 命令 长度 校验 数据...

                    # 无
                    if self.dataBuffer[0] == SERIAL_GENIUS_FS_CHAR:
                        if 0x01 <= self.dataBuffer[1] <= 0x06:
                            if self.dataBuffer[3] == self.dataBuffer[1] ^ self.dataBuffer[2]:
                                self.dataParseCurStatus = self.dataBuffer[1]
                                self.dataparseCurLength = self.dataBuffer[2]

                                self.dataBuffer.pop(0)
                                self.dataBuffer.pop(0)
                                self.dataBuffer.pop(0)
                                self.dataBuffer.pop(0)
                            else:
                                # 数据校验出错
                                self.dataBuffer.pop(0)
                                self.dataBuffer.pop(0)
                                self.dataBuffer.pop(0)
                                self.dataBuffer.pop(0)
                        else:
                            # 不是我们的数据
                            self.dataBuffer.pop(0)
                            self.dataBuffer.pop(0)
                            self.dataBuffer.pop(0)
                            self.dataBuffer.pop(0)
                    else:
                        # 不是一个帧头，在这里忽略
                        self.dataBuffer.pop(0)

                elif self.dataParseCurStatus == 0x01:
                    self.dataParseCurStatus = 0

                    # INT8U
                    item = self.GetNextDataByte()
                    value = self.GetNextDataByte()

                    if 0 <= item <= 255:
                        self.Data[item][0] = value
                        self.listData.dataChanged = True
                elif self.dataParseCurStatus == 0x02:
                    self.dataParseCurStatus = 0

                    # INT8S
                    item = self.GetNextDataByte()
                    value = self.GetNextDataByte()
                    if value > 127:
                        value = value - 0x100
                    if 0 <= item <= 255:
                        self.Data[item][1] = value
                        self.listData.dataChanged = True
                elif self.dataParseCurStatus == 0x03:
                    self.dataParseCurStatus = 0

                    # INT16U
                    item = self.GetNextDataByte()
                    valueH = self.GetNextDataByte()
                    valueL = self.GetNextDataByte()
                    value = (valueH << 8) | valueL
                    if 0 <= item <= 255:
                        self.Data[item][2] = value
                        self.listData.dataChanged = True
                elif self.dataParseCurStatus == 0x04:
                    self.dataParseCurStatus = 0

                    # INT16S
                    item = self.GetNextDataByte()
                    valueH = self.GetNextDataByte()
                    valueL = self.GetNextDataByte()
                    value = (valueH << 8) | valueL
                    if value > 0x7FFF:
                        value = value - 0x10000
                    if 0 <= item <= 255:
                        self.Data[item][3] = value
                        self.listData.dataChanged = True
                elif self.dataParseCurStatus == 0x05:
                    self.dataParseCurStatus = 0

                    # INT32U
                    item = self.GetNextDataByte()
                    valueHH = self.GetNextDataByte()
                    valueHL = self.GetNextDataByte()
                    valueLH = self.GetNextDataByte()
                    valueLL = self.GetNextDataByte()
                    value = (valueHH << 24) | (valueHL << 16) | (valueLH << 8) | valueLL
                    if 0 <= item <= 255:
                        self.Data[item][4] = value
                        self.listData.dataChanged = True
                elif self.dataParseCurStatus == 0x06:
                    self.dataParseCurStatus = 0

                    # INT32S
                    item = self.GetNextDataByte()
                    valueHH = self.GetNextDataByte()
                    valueHL = self.GetNextDataByte()
                    valueLH = self.GetNextDataByte()
                    valueLL = self.GetNextDataByte()
                    value = (valueHH << 24) | (valueHL << 16) | (valueLH << 8) | valueLL
                    if value > 0x7FFFFFFF:
                        value = value - 0x100000000
                    if 0 <= item <= 255:
                        self.Data[item][5] = value
                        self.listData.dataChanged = True
                else:
                    self.dataParseCurStatus = 0
            except:
                self.dataParseCurStatus = 0
                break
                # strs=''
                # for i in range(0,len(self.dataBuffer)):
                #    strs+=('%02X ' % self.dataBuffer[i])    
                # self.debugText.SetLabel(strs)

    # 十六进制显示模式
    def OnHexMode(self, event):
        self.hexMode = event.GetEventObject().GetValue()
        if self.hexMode:
            Config.APP_CONFIG['module_variable']['hexMode'] = '1'
        else:
            Config.APP_CONFIG['module_variable']['hexMode'] = '0'
        self.listData.Refresh()

    def OnClearData(self, event):
        for i in range(0, 6):
            for j in range(0, 256):
                self.Data[j][i] = 0
        self.listData.Refresh()
